//
//  ViewController.m
//  WallpaperDownloader
//
//  Created by huang on 2018/9/7.
//  Copyright © 2018年 wdys. All rights reserved.
//

#import "ViewController.h"
typedef NSImage WDImage;

@interface WDImageFileManager :NSObject
@property (nonatomic, copy)NSString *outDir;
+ (instancetype)shareInstance;
- (void)moveToOrignalDir:(NSURL *)url filename:(NSString *)name;
- (void)writeToCompressDir:(WDImage *)img filename:(NSString *)name;
- (void)writeToThumbnailDir:(WDImage *)img filename:(NSString *)name;
@end

@implementation WDImageFileManager
+ (instancetype)shareInstance{
    static WDImageFileManager *instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [WDImageFileManager new];
    });
    return instance;
}
- (void)moveToOrignalDir:(NSURL *)url filename:(NSString *)name{
    NSString *dir = [self.outDir stringByAppendingPathComponent:@"orignal"];
    if (![[NSFileManager defaultManager] fileExistsAtPath:dir]) {
        [[NSFileManager defaultManager] createDirectoryAtPath:dir withIntermediateDirectories:YES attributes:nil error:nil];
    }
    NSString *filePath = [dir stringByAppendingPathComponent:name];
    [[NSFileManager defaultManager] moveItemAtURL:url toURL:[NSURL fileURLWithPath:filePath]  error:nil];
}
- (void)writeToCompressDir:(WDImage *)img filename:(NSString *)name{
    NSData *data = [img TIFFRepresentation];
    NSString *dir = [self.outDir stringByAppendingPathComponent:@"compress"];
    if (![[NSFileManager defaultManager] fileExistsAtPath:dir]) {
        [[NSFileManager defaultManager] createDirectoryAtPath:dir withIntermediateDirectories:YES attributes:nil error:nil];
    }
    NSString *filePath = [dir stringByAppendingPathComponent:name];
    [data writeToURL:[NSURL fileURLWithPath:filePath] atomically:YES];
}
- (void)writeToThumbnailDir:(WDImage *)img filename:(NSString *)name{
    NSData *data = [img TIFFRepresentation];
    NSString *dir = [self.outDir stringByAppendingPathComponent:@"thumbnail"];
    if (![[NSFileManager defaultManager] fileExistsAtPath:dir]) {
        [[NSFileManager defaultManager] createDirectoryAtPath:dir withIntermediateDirectories:YES attributes:nil error:nil];
    }
    NSString *filePath = [dir stringByAppendingPathComponent:name];
    [data writeToURL:[NSURL fileURLWithPath:filePath] atomically:YES];
}

@end

@interface WDDownLoadOperation:NSObject <NSURLSessionDownloadDelegate>
+ (NSURLSession *)downloadSession;
@property (nonatomic, assign)NSURL *imageUrl;
@property (nonatomic, strong)WDImage *image;
@property (nonatomic, assign)dispatch_semaphore_t sema;
@end
@implementation WDDownLoadOperation
+ (NSURLSession *)downloadSession{
    static NSURLSession *session = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSURLSessionConfiguration *config = [NSURLSessionConfiguration ephemeralSessionConfiguration];
        session = [NSURLSession sessionWithConfiguration:config];
    });
    return session;
}
- (void)start{
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDownloadTask *task = [session downloadTaskWithURL:self.imageUrl completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error) {
            NSLog(@"%@",error);
        }
        self.image = [[NSImage alloc] initWithContentsOfURL:location];
        [[WDImageFileManager shareInstance] moveToOrignalDir:location filename:[self.imageUrl lastPathComponent]];
        dispatch_semaphore_signal(self.sema);
    }];
    [task resume];
}



@end
@interface WDCompressionOperation: NSObject
@property (nonatomic, assign)NSURL *imageUrl;
@property (nonatomic, strong)WDImage *orignalImage;
@property (nonatomic, strong)WDImage *compressionIMG;
@end
@implementation WDCompressionOperation
- (void)start{
    if (self.orignalImage && !CGSizeEqualToSize(self.orignalImage.size, CGSizeZero)) {
        WDImage *image = self.orignalImage;
        CGSize imagesize = image.size;
        CGFloat aspect = imagesize.width / imagesize.height;
        
        CGSize targetsize = CGSizeMake(0, 0);
        CGFloat minValue = 1000;
        CGFloat min = MIN(imagesize.width, imagesize.height);
        if (min > minValue) {
            if (min == imagesize.width) {
                targetsize.width = minValue;
                targetsize.height = targetsize.width / aspect;
            }else{
                targetsize.height = minValue;
                targetsize.width = minValue * aspect;
            }
        }
        CGRect rect = CGRectMake(0, 0, targetsize.width, targetsize.height);
        size_t width = targetsize.width;
        size_t height = targetsize.height;
        CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
        const size_t bitsPerComponent = 8;
        const size_t bytesPerRow = width * 4;
        CGContextRef ctx = CGBitmapContextCreate(NULL, width, height, bitsPerComponent, bytesPerRow, colorspace, kCGImageAlphaPremultipliedLast);
        [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithCGContext:ctx flipped:NO]];
        [image drawInRect:rect];
        CGImageRef compressionIMGRef =  CGBitmapContextCreateImage(ctx);
        WDImage *compressionIMG = [[WDImage alloc] initWithCGImage:compressionIMGRef size:targetsize];
        self.compressionIMG = compressionIMG;
        [[WDImageFileManager shareInstance] writeToCompressDir:compressionIMG filename:[self.imageUrl lastPathComponent]];
        CGImageRelease(compressionIMGRef);
        CGColorSpaceRelease(colorspace);
        CGContextRelease(ctx);
    }
}
@end

@interface WDThumbnailOperation : NSObject
@property (nonatomic, assign)NSURL *imageUrl;
@property (nonatomic, strong)WDImage *orignalImage;
@property (nonatomic, strong)WDImage *thumbnailIMG;
@end
@implementation WDThumbnailOperation
- (void)start{
    if (self.orignalImage && !CGSizeEqualToSize(self.orignalImage.size, CGSizeZero)) {
        WDImage *image = self.orignalImage;
        CGSize imagesize = image.size;
        CGFloat aspect = imagesize.width / imagesize.height;
        
        CGSize targetsize = CGSizeMake(0, 0);
        CGFloat minValue = 200;
        CGFloat min = MIN(imagesize.width, imagesize.height);
        if (min > minValue) {
            if (min == imagesize.width) {
                targetsize.width = minValue;
                targetsize.height = targetsize.width / aspect;
            }else{
                targetsize.height = minValue;
                targetsize.width = minValue * aspect;
            }
        }
        CGRect rect = CGRectMake(0, 0, targetsize.width, targetsize.height);
        size_t width = targetsize.width;
        size_t height = targetsize.height;
        CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
        const size_t bitsPerComponent = 8;
        const size_t bytesPerRow = width * 4;
        CGContextRef ctx = CGBitmapContextCreate(NULL, width, height, bitsPerComponent, bytesPerRow, colorspace, kCGImageAlphaPremultipliedLast);
        [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithCGContext:ctx flipped:NO]];
        [image drawInRect:rect];
        CGImageRef thumbnailImgRef =  CGBitmapContextCreateImage(ctx);
        WDImage *thumbnailIMG = [[WDImage alloc] initWithCGImage:thumbnailImgRef size:targetsize];
        self.thumbnailIMG = thumbnailIMG;
        [[WDImageFileManager shareInstance] writeToThumbnailDir:thumbnailIMG filename:[self.imageUrl lastPathComponent]];
        CGImageRelease(thumbnailImgRef);
        CGColorSpaceRelease(colorspace);
        CGContextRelease(ctx);
    }
}
@end

@interface WDImageSource: NSOperation
@property (nonatomic, assign)int progress;
@property (nonatomic, copy)NSURL *imageUrl;
@property (nonatomic, strong)WDDownLoadOperation *downloadOp;
@property (nonatomic, weak)WDCompressionOperation *compresssOp;
@property (nonatomic, weak)WDThumbnailOperation *thumbnailOp;
@end
@implementation WDImageSource
+ (NSOperationQueue *)operationQueue{
    static NSOperationQueue *queue = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        queue = [NSOperationQueue new];
        queue.maxConcurrentOperationCount = 10;
    });
    return queue;
}
- (void)start{
//    [super start];
    dispatch_semaphore_t sema = dispatch_semaphore_create(0);
    WDDownLoadOperation *downloadOp = [WDDownLoadOperation new];
    downloadOp.imageUrl = self.imageUrl;
    downloadOp.sema = sema;
    self.downloadOp = downloadOp;
    [downloadOp start];
    
    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
    WDImage *orignalImage = downloadOp.image;
    
    WDCompressionOperation *compressOp = [WDCompressionOperation new];
    compressOp.orignalImage = orignalImage;
    compressOp.imageUrl = self.imageUrl;
    self.compresssOp = compressOp;
    [compressOp start];
    
    WDThumbnailOperation *thumbnailOp = [WDThumbnailOperation new];
    thumbnailOp.orignalImage = orignalImage;
    thumbnailOp.imageUrl = self.imageUrl;
    self.thumbnailOp = thumbnailOp;
    [thumbnailOp start];
    [super start];
    [self completionBlock];
}
@end
@interface ViewController()
@property (weak) IBOutlet NSTextField *tagsField;
@property (weak) IBOutlet NSTextField *outField;
@property (strong) NSMutableArray *operations;
@end
@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}

- (IBAction)download:(id)sender {
    [WDImageFileManager shareInstance].outDir = self.outField.stringValue;
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSData *data = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:@"/Users/huang/Desktop/WallPapaerSpider/output/_food.json"]];
        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
        NSMutableArray *sources = [NSMutableArray array];
        NSArray *urls = dic.allValues.firstObject;
        for (NSString *url in urls) {
            WDImageSource *source = [WDImageSource new];
            source.imageUrl = [NSURL URLWithString:url];
            [[WDImageSource operationQueue] addOperation:source];
            [sources addObject:source];
        }
        dispatch_sync(dispatch_get_main_queue(), ^{
            self.operations = [sources mutableCopy];
        });
    });
}


- (void)setRepresentedObject:(id)representedObject {
    [super setRepresentedObject:representedObject];

    // Update the view, if already loaded.
}


@end
